/**
 * 
 */
package org.dce.screencapturer;

import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import javax.imageio.ImageIO;

@SuppressWarnings("serial")
public class ImageTransferer 
	implements Transferable,
	Serializable{
	
	private final BufferedImage image;

	private static final DataFlavor PNG_FLAVOR = new DataFlavor("image/png","PNG Image");
	private static final DataFlavor JPG_FLAVOR = new DataFlavor("image/jpg","JPG Image");
	private static final DataFlavor BMP_FLAVOR = new DataFlavor("image/bmp","BMP Image");
	
	private static final DataFlavor PNG_FILE_FLAVOR = new DataFlavor("image/png","PNG File");
	private static final DataFlavor JPG_FILE_FLAVOR = new DataFlavor("image/jpg","JPG File");
	private static final DataFlavor BMP_FILE_FLAVOR = new DataFlavor("image/bmp","BMP File");
	
	private static final Set<DataFlavor> IMAGE_FLAVORS = new HashSet<DataFlavor>(Arrays.asList(
			PNG_FLAVOR,
			JPG_FLAVOR,
			BMP_FLAVOR));
	
	private static final Set<DataFlavor> FILE_IMAGE_FLAVORS = new HashSet<DataFlavor>(Arrays.asList(
			PNG_FILE_FLAVOR,
			JPG_FILE_FLAVOR,
			BMP_FILE_FLAVOR));
	
	private static final Set<DataFlavor> FLAVORS = new HashSet<DataFlavor>();
	
	static {
		FLAVORS.addAll(IMAGE_FLAVORS);
		FLAVORS.addAll(FILE_IMAGE_FLAVORS);
		FLAVORS.add(DataFlavor.imageFlavor);
	}
	
	public ImageTransferer(BufferedImage image) {
		this.image = image;
	}

	@Override
	public boolean isDataFlavorSupported(DataFlavor flavor) {
		return FLAVORS.contains(flavor);
	}

	@Override
	public DataFlavor[] getTransferDataFlavors() {
		return FLAVORS.toArray(new DataFlavor[FLAVORS.size()]);
	}

	@Override
	public Object getTransferData(DataFlavor flavor)
			throws UnsupportedFlavorException, IOException {
		
		if (flavor == DataFlavor.imageFlavor){
			return image;
		} else if (FILE_IMAGE_FLAVORS.contains(flavor)){
			return toFile(encodeToArray(image,flavor.getSubType()));
		} else if (IMAGE_FLAVORS.contains(flavor)){
			return encode(image,flavor.getSubType());
		}
		
		throw new UnsupportedFlavorException(flavor);
	}

	private Object toFile(byte[] data) throws IOException {
		
		File file = File.createTempFile("screencapturer.", "."+System.currentTimeMillis()+".png");

		FileOutputStream output = new FileOutputStream(file);
		output.write(data);
		output.flush();
		output.close();
		
		return file;
	}

	private InputStream encode(BufferedImage image, String formatName) 
		throws IOException {
		return new ByteArrayInputStream(encodeToArray(image, formatName));
	}

	private byte[] encodeToArray(BufferedImage image, String formatName) 
		throws IOException {
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		ImageIO.write(image, formatName, output);
		return output.toByteArray();
	}


}